import time
from functools import wraps
from urllib.parse import urlparse

from rest_framework import exceptions
from rest_framework.response import Response

from configer import LOG
from utils.my_jwt import MiniJWT
from utils.my_redis import get_image_cache_success, remove_image_cache_success, get_qrcode_cache_success, \
	remove_qrcode_cache_success, get_user_status


def login_and_auth_middleware(func):
	"""登录和权限校验"""
	m = MiniJWT()

	@wraps(func)
	def wrapper(self, request, *args, **kwargs):
		token = request.META.get('HTTP_TOKEN')
		url = urlparse(request.get_full_path()).path
		x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
		if x_forwarded_for:
  			ip = x_forwarded_for.split(',')[0]#所以这里是真实的ip
		else:
  			ip = request.META.get('REMOTE_ADDR')#这里获得代理ip
		ua = request.META.get('HTTP_USER_AGENT', '')
		# LOG.info(f"权限校验访问ip：--> {str(ip)}  {ua}  {token}")
		# print(token, "this")
		status, uid, time_, level = m.check(token, ip, ua)
		if status:
			request.META['mini_uid'] = uid
			res = func(self, request, *args, **kwargs)
			if m.get_limit_time(time_):
				res.set_cookie('jwtToken', m.refresh(uid, level, ip, ua))
		else:
			res = {"message": '校验失败 登录失效 请重新登录', "code": 30001}
		# print(res.data, res.get('code'), res.status_code)
		return res if isinstance(res, Response) else Response(res)
	return wrapper


def auth_middleware(need_level):
	"""登录校验"""
	m = MiniJWT()
	def large(func):
		@wraps(func)
		def wrapper(self, request, *args, **kwargs):
			token = request.META.get('HTTP_TOKEN')
			url = urlparse(request.get_full_path()).path
			if request.META.get('HTTP_X_FORWARDED_FOR'):
				ip = request.META.get("HTTP_X_FORWARDED_FOR")
			else:
				ip = request.META.get("REMOTE_ADDR")
			ua = request.META.get('HTTP_USER_AGENT', '')
			status, uid, time_, level = m.check(token, ip, ua)
			print(level, need_level, 'level')
			if level >= need_level:
				request.META['mini_uid'] = uid
				res = func(self, request, *args, **kwargs)
				if m.get_limit_time(time_):
					res.set_cookie('jwtToken', m.refresh(uid, level, ip, ua))
			else:
				res = {"message": '抱歉 你没有该操作权限', "code": 30001}
			return res if isinstance(res, Response) else Response(res)
		return wrapper
	return large




def image_cache_middleware(func):
	"""图形验证码"""

	@wraps(func)
	def wrapper(self, request, *args, **kwargs):
		uuid = request.GET.get('uuid', None)
		if not uuid or not get_image_cache_success(uuid=uuid):
			res = {"message": '缺少关键参数或验证错误', "code": 30001}
		else:
			res = func(self, request, *args, **kwargs)
			if res.data.get("code") == 200:
				remove_image_cache_success(uuid=uuid)
		return res if isinstance(res, Response) else Response(res)

	return wrapper


def user_status_middleware(func):

	@wraps(func)
	def wrapper(self, request, *args, **kwargs):
		if request.META.get('HTTP_X_FORWARDED_FOR'):
			ip = request.META.get("HTTP_X_FORWARDED_FOR")
		else:
			ip = request.META.get("REMOTE_ADDR")
		# user_status = "2" if get_user_status(ip) else "1"
		user_status = "1" if int(time.time()) % 3 else "2"
		request.META['user_status'] = user_status
		res = func(self, request, *args, **kwargs)
		return res if isinstance(res, Response) else Response(res)

	return wrapper


from rest_framework.authentication import SessionAuthentication


class CsrfExemptSessionAuthentication(SessionAuthentication):
	"""
	代码解析：
	编写一个类继承自 SessionAuthentication, 重写 enforce_csrf 方法，
	如果返回一个 None,则代表不执行之前发生的 csrf 检查。
	"""
	def enforce_csrf(self, request):
		return  # To not perform the csrf check previously happening


def used_time(func):

	def middle(request, *args, **kwargs):
		start = time.time()
		res = func(request, *args, **kwargs)
		end = time.time()
		print(f'used time {int((end-start) * 1000)} ms')
		return res
	return middle
